import { NestFactory } from '@nestjs/core'
import { ConfigService } from '@nestjs/config'
import { AppModule } from '@/app.module'
import { NestExpressApplication } from '@nestjs/platform-express'
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'
import { exec } from 'child_process'
import { Logger } from '@nestjs/common'
import * as cors from 'cors'
import * as session from 'express-session'
import * as util from 'util'
import { join } from 'path'

const logger = new Logger('Bootstrap')

// 将 exec 转换为 Promise 形式
const execPromise = util.promisify(exec)

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule)
  const configService = app.get(ConfigService)

  // 设置静态资源访问目录
  app.useStaticAssets(join(__dirname, 'public'), {
    prefix: '/api/static'
  })

  // 配置 CORS 中间件
  app.use(
    cors({
      origin: (origin, callback) => {
        const allowedOrigins = configService.get<string[]>('THITE_LIST')
        if (!origin || allowedOrigins.includes(origin)) {
          callback(null, true)
        } else {
          callback(new Error('Not allowed by CORS'))
        }
      }
    })
  )

  app.use(
    session({
      secret: configService.get<string>('JWT_SECRET'),
      rolling: true,
      cookie: { maxAge: null },
      resave: false,
      saveUninitialized: true
    })
  )

  // 设置全局路由前缀
  app.setGlobalPrefix('api')

  // Swagger 文档配置
  const options = new DocumentBuilder().setTitle('WMTS/WMS - Tools 接口文档').setDescription('提供给 Gaogy 使用的接口文档').setVersion('1.0').build()
  const document = SwaggerModule.createDocument(app, options)
  SwaggerModule.setup('/api-docs', app, document)

  const port = configService.get<number>('SERVER_PORT', 3000)
  await app.listen(port)
  logger.log(`Application is running on: http://localhost:3000`)
}

async function copyAssets() {
  try {
    const command = 'mkdirp ./dist/images && ncp ./src/public/images ./dist/images'
    const command1 = 'mkdirp ./dist/public && ncp ./src/public ./dist/public'
    await execPromise(command)
    await execPromise(command1)
    logger.log('📁 静态资源复制成功')
  } catch (error) {
    logger.error(`复制静态资源失败: ${error.message}`)
  }
}

async function startup() {
  const startTime = Date.now()
  const isProd = process.env.NODE_ENV === 'prod'
  if (!isProd) await copyAssets()
  await bootstrap()
  const endTime = Date.now()
  const duration = endTime - startTime
  logger.log(`🚀🚀🚀 服务启动完成，耗时: ${duration}ms`)
}

startup()
